package com.graphics;

import java.awt.image.*;
import java.util.ArrayList;

/**
 * @author  Sajarwo Anggai
 */
public class ImageAnimator {

    private boolean isRepeating;
    private boolean ticksIgnored;
    private int animPeriod;
    // waktu yang dibutuhkan untuk satu animasi (dalam milidetik)
    private long animTotalTime;
    private int showPeriod;
    // Waktu untuk menampilkan animasi saat ini (dalam milidetik)
    private double seqDuration;
    // total waktu yang dibutuhkan untuk keseluruhan animasi
    private int numImages;	  // jumlah keseluruhan gambar
    private int imPosition;     // Posisi gambar terkini
    private ImageSequenceListener listener = null;

    private ArrayList spriteFrame;
    public ImageAnimator(int ap, double d, boolean isr, ArrayList spriteFrame) {
        animPeriod = ap;
        seqDuration = d;
        isRepeating = isr;
        animTotalTime = 0L;
        this.spriteFrame = spriteFrame;

        if (seqDuration < 0.5) {
            System.out.println("Warning: minimum sequence duration is 0.5 sec.");
            seqDuration = 0.5;
        }

        numImages = spriteFrame.size();
        imPosition = 0;
        ticksIgnored = false;
        showPeriod = (int) (1000 * seqDuration / numImages);

    }

    public void updateTick() /* diasumsikan method ini di panggil sesuai dengan periode animasi (dalam ms)  */ {
        if (!ticksIgnored) {
            // update total waktu animasi, modulo waktu animasi dengan durasi sequence
            animTotalTime = (animTotalTime + animPeriod) % (long) (1000 * seqDuration);

            // menghitung image terkini
            imPosition = (int) (animTotalTime / showPeriod);   // dalam jarak 0 sampai jumlah gambar-1

            if ((imPosition == numImages - 1) && (!isRepeating)) {  // sequence selesai
                ticksIgnored = true;   // update tick diabaikan
                if (listener != null) {
                    listener.sequenceEnded("Finished");   // mengirimkan pesan ke listener
                }
            }
        }
    }

    public BufferedImage getCurrentImage() {
        if (numImages != 0) {
            return (BufferedImage)spriteFrame.get(imPosition);
        } else {
            return null;
        }
    }

    public int getCurrentPosition() {
        return imPosition;
    }

    public void addImageSequenceListener(ImageSequenceListener l) {
        listener = l;
    }

    public void stop() /* update tick diabaikan */ {
        ticksIgnored = true;
    }

    public boolean isStopped() {
        return ticksIgnored;
    }

    public boolean atSequenceEnd() // check apakah sequence selesai
    {
        return ((imPosition == numImages - 1) && (!isRepeating));
    }

    public void stopAt(int pos) {
        imPosition = pos;
        ticksIgnored = true;
    }

    public void restartAt(int imPosn) /* memulai menampilkan gambar sesuai dengan posisi yang diberikan */ {
        if (numImages != 0) {
            if ((imPosn < 0) || (imPosn > numImages - 1)) {
                System.out.println("Out of range restart, starting at 0");
                imPosn = 0;
            }

            imPosition = imPosn;

            animTotalTime = (long) imPosition * showPeriod;
            ticksIgnored = false;
        }
    }

    public void resume() {
        if (numImages != 0) {
            ticksIgnored = false;
        }
    }
}